package suites.queue {
	import suites.queue.mock.AsyncQable;
	import suites.queue.mock.ImmediateQable;

	import org.flexunit.asserts.assertEquals;
	import org.splink.library.queue.IQ;
	import org.splink.library.queue.IQable;
	import org.splink.library.queue.ParallelQ;
	import org.splink.library.queue.Q;
	import org.splink.library.queue.QEvent;

	/**
	 * @author Max Kugland
	 */
	public class ParallelQResetTest extends AbstractQTest {

		/**
		 * @inheritDoc
		 */
		override protected function qImpl(id : String) : IQ {
			return new ParallelQ(id);
		}
		
		[Test]
		public function emptyReset() : void {
			_q.reset();
		}
		
		[Test]
		public function oneReset() : void {
			_q.add(new ImmediateQable());
			_q.reset();
			assertEquals(1, Q.getTotal(_q));
		}
		
		[Test]
		public function nestedReset() : void {
			var q1 : IQ = createQ(3);			var q2 : IQ = createQ(2);			var q3 : IQ = createQ(1);			var q4 : IQ = createQ(3);
			_q.add(q1);
			q1.add(q2);
			q2.add(q3);
			q2.add(q4);
			_q.reset();
			
			assertEquals(13, Q.getTotal(_q));
		}
		
		[Test(async)]
		public function runningReset() : void {
			handleAsync(2000);
			
			_q.add(new ImmediateQable("1"));			_q.add(new AsyncQable("2"));
			_q.add(new AsyncQable("3"));
			_q.add(new AsyncQable("4"));
			assertEquals(4, Q.getTotal(_q));
			
			var a : Array = new Array();
			Q.visit(_q, function(n : IQable):void {
				n.register(QEvent.COMPLETE, function(e : QEvent):void {
					a.push(e.source);
					if(a.length == 3) {
						_q.reset();
						_q.start();
					}
				});
			});			
			
			_q.register(QEvent.COMPLETE, function(e : QEvent):void {
				assertEquals(7, a.length); 
			}, null, 1000);				
			
			_q.start();	
		}
		
		[Test(async)]
		public function nestedRunningReset() : void {
			handleAsync(6000);
			var q1 : IQ = createQ(3); //q0
			var q2 : IQ = createQ(2); //q4
			var q3 : IQ = createQ(1); //q7
			var q4 : IQ = createQ(3); //q9
			_q.add(q1);
			q1.add(q2);
			q2.add(q3);
			q2.add(q4);
			
			assertEquals(13, Q.getTotal(_q));
			
			var a : Array = new Array();
			Q.visit(_q, function(qable : IQable):void {
				qable.register(QEvent.COMPLETE, function(e : QEvent):void {
					a.push(e.source);
					if(a.length == 12) {
						_q.reset();
						_q.start();
					}
				});
			});		
			
			_q.register(QEvent.COMPLETE, function(e : QEvent):void {
				assertEquals(25, a.length);
			}, null, 1000);
			
			_q.start();
		}
	}
}
